<?php

namespace s94\wechat;

/**
 * 微信公众号自定义菜单管理
 */
class Menu extends Base
{
    public $menuButton = [];
    public static $menuTypeMap = [
        'click'=>'点击事件',
        'view'=>'网页',
        'miniprogram'=>'小程序',
        'scancode_push'=>'扫码推事件',
        'scancode_waitmsg'=>'扫码带提示',
        'pic_sysphoto'=>'拍照发图',
        'pic_photo_or_album'=>'拍照或相册发图',
        'pic_weixin'=>'微信相册发图',
        'location_select'=>'发送位置',
        'article_id'=>'图文消息',
        'article_view_limited'=>'打开图文',
    ];

    private function button($config)
    {
        self::assert(!empty($config['name']), '菜单名称不能为空');
        self::assert(!empty($config['type']) && isset(self::$menuTypeMap[$config['type']]), '菜单类型参数错误');
        $keys = ['name', 'type'];
        switch ($config['type']){
            case 'media_id': case 'view_limited': $keys[] = 'media_id'; break;
            case 'article_id': case 'article_view_limited': $keys[] = 'article_id'; break;
            case 'miniprogram': {
                $keys[] = 'appid';
                $keys[] = 'pagepath';
            }
            case 'view': $keys[] = 'url'; break;
            default: $keys[] = 'key'; break;
        }
        $res = [];
        foreach ($keys as $k){
            self::assert(!empty($config[$k]), "菜单参数 {$k} 不能为空");
            $res[$k] = $config[$k];
        }
        return $res;
    }

    /**添加菜单按钮，添加的为一级菜单按钮，如果此菜单按钮具有子菜单，$config参数传入二维数组即可
     * @param string $name 标题，注意：$config里面的name参数具备更高优先级
     * @param array $config 配置，仅一级菜单格式：['type'=>'click','key'=>'']；含子菜单格式：[['name'=>'标题1','type'=>'click','key'=>''], [...], ...]
     * @return $this
     * @throws \Exception
     */
    public function addButton($name, array $config)
    {
        if (isset($config[0]) && is_array($config[0])){
            self::assert(count($config) <= 5, '最多包含5个二级菜单');
            $button = ['name'=>$name, 'sub_button'=>[]];
            foreach ($config as $v){
                $button['sub_button'][] = $this->button($v);
            }
        }else{
            $config['name'] = $config['name'] ?? $name;
            $button = $this->button($config);
        }
        $this->menuButton[] = $button;
        return $this;
    }

    /**创建自定义菜单，需要先调用 addButton 方法添加菜单按钮，创建后，会清空之前添加的菜单按钮
     * @param mixed $tag_id 用户标签的id，可通过用户标签管理接口获取，传入表示个性化菜单
     * @return mixed
     * @throws SdkException
     */
    public function create($tag_id=null)
    {
        self::assert(count($this->menuButton), '菜单按钮为空，请先使用【addButton】方法添加按钮');
        $post_data = ['button'=>$this->menuButton];
        if ($tag_id){
            $post_data['matchrule'] = ['tag_id'=>$tag_id];
            $res = $this->apiSdk('cgi-bin/menu/addconditional', ['access_token'=>$this->accessToken()], json_encode($post_data,JSON_UNESCAPED_UNICODE));
        }else{
            $res = $this->apiSdk('cgi-bin/menu/create', ['access_token'=>$this->accessToken()], json_encode($post_data,JSON_UNESCAPED_UNICODE));
        }
        $this->menuButton = [];
        return $res;
    }

    /**获取默认的菜单配置
     * @return array 菜单按钮配置，格式：[['name'=>'按钮名称','type'=>'click','key'=>'KEY','sub_button'=>[...]],...]
     * @throws SdkException
     */
    public function info()
    {
        $res = $this->apiSdk('cgi-bin/menu/get', ['access_token'=>$this->accessToken()]);
        return $res['menu']['button'];
    }

    /**获取所有的菜单配置，包括个性化配置
     * @return array 格式：[0=>默认的菜单配置, '用户的标签ID'=>对应个性化的菜单配置, ...]
     * @throws SdkException
     */
    public function infoAll()
    {
        $res = $this->apiSdk('cgi-bin/menu/get', ['access_token'=>$this->accessToken()]);
        $tag_list = [];
        if (isset($res['conditionalmenu'])){
            foreach ($res['conditionalmenu'] as $row){
                $tag_id = $row['matchrule']['tag_id'] ?? '';
                if ($tag_id) $tag_list[$tag_id] = $row['button'];
            }
        }
        $tag_list[] = $res['menu']['button'];
        return $tag_list;
    }


}
